<script lang="ts" setup>
import { CheckOutlined, CloseOutlined, EditOutlined, PlusOutlined } from '@ant-design/icons-vue'
import { v4 } from 'uuid'
import AddCover from '@/components/AddCover.vue'
import _ from 'lodash-es'
import { ref, watch } from 'vue'
import { useGoodsForm } from '../composables/useGoodsForm'
import { useI18n } from 'vue-i18n'
import Api from '@/libs/api'
import Tool from '@/libs/utils/Tool'
import Demos from '@/datas/Demos'

const { t } = useI18n()

interface Props {
	editForm: any
	canEditSkuAttrs: boolean
	skuColumns: any[]
	skuSelects: any[]
	attrVSelects: string[]
}

interface Emits {
	(e: 'generate-skus'): void
	(e: 'change-sel-skus', selectedRowKeys: any[], selectedRows: any[]): void
	(e: 'sel-attr-v'): void
}

const props = defineProps<Props>()
const emit = defineEmits<Emits>()

const skuBatchCoverChange = ref<HTMLInputElement>()
const batchQuantitySetInputs = ref<Record<string, HTMLInputElement>>({})
const batchPriceSetInputs = ref<Record<string, HTMLInputElement>>({})

const conf = {
	maxAttrKLen: 3,
	maxAttrVLen: 20,
	maxKeyWordCount: 20,
	maxKeyWordLength: 50,
	longKeyWordTagLength: 20
}

// 从 useGoodsForm 中获取 getToAddSkuColumnsMap 相关函数
const { getToAddSkuColumnsMap } = useGoodsForm()

const { locale } = useI18n()
const toAddSkuColumnsMap = getToAddSkuColumnsMap()

// 监听语言变化，重新生成SKU表头
watch(locale, () => {
	// 当语言变化时，触发重新生成SKU
	emit('generate-skus')
})

const addAttrK = () => {
	if (props.editForm.attrs.length === conf.maxAttrKLen) {
		Api.notify(t('通知.sku规格限制', { maxAttrKLen: conf.maxAttrKLen }))
	} else {
		const attr = {
			id: 0,
			uuid: v4(),
			isEditing: true,
			vEditingCount: 0,
			k: '',
			v: []
		}
		props.editForm.attrs.push(attr)
	}
}

const delAttrK = (key: number) => {
	props.editForm.attrs.splice(key, 1)
	if (props.editForm.attrs.length > 0) {
		emit('generate-skus')
	} else {
		props.editForm.skus = []
	}
}

const doSaveAttrK = (key: number) => {
	if (!props.editForm.attrs[key].k) {
		Api.notify(t('通知.sku属性名必填'))
	} else {
		const attrKKs = props.editForm.attrs.map(item => item.k)
		if (Tool.hasDuplicates(attrKKs)) {
			Api.notify(t('通知.sku属性名重复'))
			return false
		}
		props.editForm.attrs[key].isEditing = false
		props.skuColumns.forEach((column, key) => {
			if (
				column &&
				column.dataIndex &&
				props.editForm.attrs[key] &&
				column.dataIndex === props.editForm.attrs[key].uuid
			) {
				column.title = props.editForm.attrs[key].k
			}
		})
	}
}

const addAttrV = (kKey: number) => {
	if (props.editForm.attrs[kKey].v.length === conf.maxAttrVLen) {
		Api.notify(t('通知.sku属性值限制', { maxAttrVLen: conf.maxAttrVLen }))
	} else {
		const attrV = {
			id: 0,
			uuid: v4(),
			isEditing: true,
			isSel: false,
			value: ''
		}
		props.editForm.attrs[kKey].v.push(attrV)
		props.editForm.attrs[kKey].vEditingCount++
		emit('generate-skus')
	}
}

const editAttrV = (kKey: number, vKey: number) => {
	props.editForm.attrs[kKey].v[vKey].isEditing = true
	props.editForm.attrs[kKey].vEditingCount++
}

const doSaveAttrV = (kKey: number, vKey: number) => {
	if (!props.editForm.attrs[kKey].v[vKey].value) {
		Api.notify(t('通知.sku属性值必填'))
	} else {
		const attrVValues = props.editForm.attrs[kKey].v.map(item => item.value)
		if (Tool.hasDuplicates(attrVValues)) {
			Api.notify(t('通知.sku属性值重复'))
			return false
		}
		props.editForm.attrs[kKey].v[vKey].isEditing = false
		props.editForm.attrs[kKey].vEditingCount--
		props.editForm.skus.forEach((sku, key) => {
			if (
				sku[props.editForm.attrs[kKey].uuid] &&
				props.editForm.attrs[kKey].v[vKey].uuid ===
					sku[props.editForm.attrs[kKey].uuid].attrV.uuid
			) {
				sku[props.editForm.attrs[kKey].uuid].attrV = Tool.deepClone(
					props.editForm.attrs[kKey].v[vKey]
				)
			}
		})
	}
}

const delAttrV = (kKey: number, vKey: number) => {
	props.editForm.attrs[kKey].v.splice(vKey, 1)
	props.editForm.attrs[kKey].vEditingCount--
	if (props.editForm.attrs[kKey].v.length > 0) {
		emit('generate-skus')
	} else {
		delAttrK(kKey)
	}
}

const selAttrV = (kKey: number, vKey: number) => {
	if (props.editForm.attrs[kKey].v[vKey].isSel === false) {
		props.editForm.attrs[kKey].v.forEach(item => {
			item.isSel = false
		})
		props.editForm.attrs[kKey].v[vKey].isSel = true
	} else {
		props.editForm.attrs[kKey].v.forEach(item => {
			item.isSel = false
		})
		props.editForm.attrs[kKey].v[vKey].isSel = false
	}
	// 通知父组件属性值选择发生变化
	emit('sel-attr-v')
}

const checkBatchSel = () => {
	if (props.skuSelects.length === 0) {
		Api.notify(t('通知.请选择至少一个sku'))
		return false
	} else {
		return true
	}
}

const inputDefaultZero = (e: Event) => {
	const value = (e.target as HTMLInputElement).value
	if (value === '') (e.target as HTMLInputElement).value = '0'
}

const batchQuantitySet = (dataIndex: string) => {
	if (!checkBatchSel()) {
		return false
	}
	const reg = /^\d*$/
	const inputElement = batchQuantitySetInputs.value[dataIndex]
	const value = inputElement?.value
	if (!reg.test(value)) {
		Api.notify(t('通知.请输入正整数'))
		return false
	}
	props.editForm.skus.forEach((sku, key) => {
		if (_.includes(props.skuSelects, sku.key)) {
			sku[dataIndex] = value
		}
	})
}

const batchPriceSet = (dataIndex: string) => {
	if (!checkBatchSel()) {
		return false
	}
	const reg = /^\d+(\.\d{1,2})?$/
	const inputElement = batchPriceSetInputs.value[dataIndex]
	const valueStr = inputElement?.value
	const value = parseFloat(valueStr)
	if (!reg.test(valueStr)) {
		Api.notify(t('通知.请输入正数金额格式'))
		return false
	}
	props.editForm.skus.forEach((sku, key) => {
		if (_.includes(props.skuSelects, sku.key)) {
			sku[dataIndex] = value.toFixed(2)
		}
	})
}

const batchCoverSet = (dataIndex: string) => {
	if (checkBatchSel()) {
		skuBatchCoverChange.value?.click()
	}
}

const batchChangeCover = (e: Event) => {
	const file = (e.target as HTMLInputElement).files?.[0]
	if (file) {
		const coverSrc = URL.createObjectURL(file)
		props.editForm.skus.forEach((sku, key) => {
			if (_.includes(props.skuSelects, sku.key)) {
				sku.cover = coverSrc
			}
		})
	}
}

const batchCoverDelete = (dataIndex: string) => {
	if (checkBatchSel()) {
		props.editForm.skus.forEach((sku, key) => {
			if (_.includes(props.skuSelects, sku.key)) {
				sku.cover = null
			}
		})
	}
}

const consoleLogSkus = () => {
	console.log(JSON.stringify(props.editForm.skus))
}

const consoleLogAttrs = () => {
	console.log(JSON.stringify(props.editForm.attrs))
}

const consoleLogSelectedAttrVs = () => {
	console.log(JSON.stringify(props.attrVSelects))
}

const generateDemoSkus = () => {
	props.editForm.attrs = Demos.skuAttrs
	emit('generate-skus')
}
</script>

<template>
	<div class="bg-white rounded-lg shadow-sm p-6">
		<a-divider class="text-lg font-semibold mb-6">{{ t('商品详细.sku属性') }}</a-divider>
		<a-alert type="info" :message="t('商品详细.sku属性提示')" class="mb-4" />
		<a-divider :dashed="true" class="mb-6"></a-divider>
		<div class="skuOperate">
			<a-form :ref="`sku`" name="sku" :label-col="{ span: 4 }" :wrapper-col="{ span: 20 }">
				<div v-for="(item, key) in editForm.attrs" :key="item.uuid">
					<a-form-item :wrapper-col="{ span: 8 }" :class="['mb-1']">
						<a-input-group compact v-if="item.isEditing">
							<a-input
								v-model:value="item.k"
								:class="['max-w-3/4']"
								placeholder="属性名">
								<template #addonBefore>
									<div :class="['text-red']">属性名</div>
								</template>
							</a-input>
							<a-button
								v-if="canEditSkuAttrs"
								type="primary"
								danger
								:class="['max-w-1/8']"
								@click="delAttrK(key)">
								<CloseOutlined />
							</a-button>
							<a-button
								type="primary"
								:class="['max-w-1/8']"
								@click="doSaveAttrK(key)">
								<CheckOutlined />
							</a-button>
						</a-input-group>
						<h4 :class="{ 'text-xl': true }" v-else>
							{{ item.k }}
							<EditOutlined
								@click="
									() => {
										item.isEditing = true
									}
								" />
						</h4>
					</a-form-item>
					<a-form-item :wrapper-col="{ span: 24 }">
						<div :class="['flex', 'flex-wrap']">
							<div
								v-for="(itemV, keyV) in item.v"
								:key="itemV.uuid"
								:class="['inline-block']">
								<a-tag
									v-if="!itemV.isEditing"
									:class="['text-base', 'my-1']"
									:color="itemV.isSel ? 'success' : 'default'"
									@click="selAttrV(key, keyV)">
									{{ itemV.value }}
									<template #icon>
										<EditOutlined
											v-if="!itemV.isSel"
											@click.prevent="editAttrV(key, keyV)" />
									</template>
								</a-tag>
								<a-input
									v-else
									v-model:value="itemV.value"
									placeholder="属性值"
									:class="['w-64', 'mx-2']">
									<template #addonBefore v-if="canEditSkuAttrs">
										<CloseOutlined @click="delAttrV(key, keyV)" />
									</template>
									<template #addonAfter>
										<CheckOutlined @click="doSaveAttrV(key, keyV)" />
									</template>
								</a-input>
							</div>
							<div
								:class="['text-xl', 'items-center', 'mx-2']"
								v-if="
									canEditSkuAttrs &&
									item.k &&
									!item.isEditing &&
									item.vEditingCount === 0 &&
									item.v.length < conf.maxAttrVLen
								">
								<PlusOutlined @click="addAttrV(key)" />
							</div>
						</div>
					</a-form-item>
				</div>
				<a-button
					v-if="canEditSkuAttrs"
					@click="addAttrK"
					type="dashed"
					v-show="editForm.attrs.length < conf.maxAttrKLen">
					{{ t('操作.添加') }}{{ t('商品详细.属性') }}
				</a-button>
				<div v-show="false">
					<a-button @click="consoleLogAttrs">consoleLogAttrs</a-button>
					<a-button @click="consoleLogSelectedAttrVs">consoleLogSelectedAttrVs</a-button>
					<a-button @click="$emit('generate-skus')">generateSkus</a-button>
					<a-button @click="consoleLogSkus">consoleLogSkus</a-button>
					<a-button @click="generateDemoSkus">generateDemoSkus</a-button>
				</div>
			</a-form>
			<div v-if="editForm.skus.length > 0">
				<a-divider />
				<a-table
					:columns="skuColumns"
					:scroll="{ x: 1200 }"
					:bordered="true"
					:pagination="false"
					:row-selection="{
						type: 'checkbox',
						selectedRowKeys: skuSelects,
						onChange(selectedRowKeys, selectedRows) {
							$emit('change-sel-skus', selectedRowKeys, selectedRows)
						}
					}"
					:data-source="editForm.skus">
					<template #headerCell="{ title, column }">
						<template
							v-if="
								toAddSkuColumnsMap[column.dataIndex as string] &&
								toAddSkuColumnsMap[column.dataIndex as string].batchQuantitySet
							">
							<div>{{ title }}</div>
							<div>
								<input
									type="number"
									min="0"
									@input="inputDefaultZero"
									:class="{ 'w-24': true }"
									:ref="
										el => {
											if (el)
												batchQuantitySetInputs[column.dataIndex as string] =
													el as HTMLInputElement
										}
									"
									value="0" />
							</div>
							<div>
								<span
									:class="{ 'color-blue hover:cursor-pointer': true }"
									@click="batchQuantitySet(column.dataIndex as string)">
									{{ t('操作.批量设置') }}
								</span>
							</div>
						</template>
						<template
							v-if="
								toAddSkuColumnsMap[column.dataIndex as string] &&
								toAddSkuColumnsMap[column.dataIndex as string].batchPriceSet
							">
							<div>{{ title }}</div>
							<div>
								<input
									type="number"
									min="0"
									@input="inputDefaultZero"
									:class="{ 'w-24': true }"
									:ref="
										el => {
											if (el)
												batchPriceSetInputs[column.dataIndex as string] =
													el as HTMLInputElement
										}
									"
									value="0" />
							</div>
							<div>
								<span
									:class="{ 'color-blue hover:cursor-pointer': true }"
									@click="batchPriceSet(column.dataIndex as string)">
									{{ t('操作.批量设置') }}
								</span>
							</div>
						</template>
						<template
							v-if="
								toAddSkuColumnsMap[column.dataIndex as string] &&
								toAddSkuColumnsMap[column.dataIndex as string].batchImageSet
							">
							<div>{{ title }}</div>
							<div>
								<span
									:class="{ 'color-blue hover:cursor-pointer': true }"
									@click="batchCoverSet(column.dataIndex as string)">
									{{ t('操作.批量上传') }}
								</span>
								<input
									ref="skuBatchCoverChange"
									type="file"
									accept="image/*"
									v-show="false"
									@change="batchChangeCover" />
							</div>
							<div>
								<span
									:class="{ 'color-red hover:cursor-pointer': true }"
									@click="batchCoverDelete(column.dataIndex as string)">
									{{ t('操作.批量删除') }}
								</span>
							</div>
						</template>
					</template>
					<template #bodyCell="{ text, record, index, column }">
						<template
							v-if="
								toAddSkuColumnsMap[column.dataIndex as string] &&
								toAddSkuColumnsMap[column.dataIndex as string].batchQuantitySet
							">
							<div class="editable-cell">
								<div class="editable-cell-input-wrapper">
									<a-input-number
										v-model:value="record[column.dataIndex as string]" />
								</div>
							</div>
						</template>
						<template
							v-if="
								toAddSkuColumnsMap[column.dataIndex as string] &&
								toAddSkuColumnsMap[column.dataIndex as string].batchPriceSet
							">
							<div class="editable-cell">
								<div class="editable-cell-input-wrapper">
									<a-input-number
										v-model:value="record[column.dataIndex as string]" />
								</div>
							</div>
						</template>
						<template
							v-if="
								toAddSkuColumnsMap[column.dataIndex as string] &&
								toAddSkuColumnsMap[column.dataIndex as string].batchImageSet
							">
							<div class="editable-cell">
								<div class="editable-cell-input-wrapper">
									<div :class="{ 'min-w-60px': true }">
										<AddCover
											v-if="true"
											v-model="record[column.dataIndex as string]" />
									</div>
								</div>
							</div>
						</template>
					</template>
				</a-table>
			</div>
		</div>
	</div>
</template>

<style lang="scss" scoped></style>
